import {
  ArrayMaxSize,
  IsArray,
  IsEnum,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  IsString,
  Length,
  Matches,
  Max,
  Min,
} from 'class-validator';
import { Transform } from 'class-transformer';
import { ArticleStatus } from '@/modules/article/entities/article.entity';

export class QueryArticleDto {
  @Min(1, { message: '页数不能小于1' })
  @IsNumber({}, { message: '页数必须为数字' })
  @Transform((params) => Number(params.value))
  pageNo: number = 1;

  @Max(100, { message: '每页数量不能大于100' })
  @Min(1, { message: '每页数量不能小于1' })
  @IsNumber({}, { message: '每页数量必须为数字' })
  @Transform((params) => Number(params.value))
  pageSize: number = 10;

  @Matches(RegExp('ASC|DESC'), { message: '排序方式错误' })
  @Transform((params) => String(params.value).toUpperCase())
  @IsOptional()
  sort?: 'ASC' | 'DESC' = 'DESC';

  @IsString({ message: '排序字段必须为字符串' })
  @IsOptional()
  orderBy?: string;
}

export class CreateArticleDto {
  @Length(1, 100, { message: '标题长度为1-100' })
  @IsNotEmpty({ message: '标题不能为空' })
  title: string;

  @Length(1, 255, { message: '描述长度为1-255' })
  @IsNotEmpty({ message: '描述不能为空' })
  description: string;

  @IsNotEmpty({ message: '内容不能为空' })
  content: string;

  @IsString({ message: '封面必须为字符串' })
  @IsOptional()
  coverSrc: string;

  @ArrayMaxSize(3, { message: '分类不能超过三个' })
  @IsNumber({}, { message: '分类ID数组元素必须是数字', each: true })
  @IsArray({ message: '分类ID必须是数组' })
  @IsNotEmpty({ message: '分类ID不能为空' })
  categoryIds: number[];

  @ArrayMaxSize(3, { message: '标签不能超过三个' })
  @IsNumber({}, { message: '标签ID数组元素必须是数字', each: true })
  @IsArray({ message: '标签ID必须是数组' })
  @IsNotEmpty({ message: '标签ID不能为空' })
  tagIds: number[];

  @Matches(RegExp('draft|pending'), { message: '状态只有 draft / pending' })
  @IsNotEmpty({ message: '状态不能为空' })
  status: ArticleStatus.DRAFT | ArticleStatus.PENDING;

  @IsNotEmpty({ message: '公开时间不能为空' })
  publicDate: Date;
}

export class UpdateArticleDto {
  @Length(1, 100, { message: '标题长度为1-100' })
  @IsOptional()
  title: string;

  @Length(1, 255, { message: '描述长度为1-255' })
  @IsOptional()
  description: string;

  @IsString({ message: '内容必须为字符串' })
  @IsOptional()
  content: string;

  @ArrayMaxSize(3, { message: '分类不能超过三个' })
  @IsNumber({}, { message: '分类ID元素必须是数字', each: true })
  @IsArray({ message: '分类ID必须是数组' })
  @IsOptional()
  categoryIds: number[];

  @ArrayMaxSize(3, { message: '标签不能超过三个' })
  @IsNumber({}, { message: '标签ID元素必须是数字', each: true })
  @IsArray({ message: '标签ID必须是数组' })
  @IsOptional()
  tagIds: number[];
}

export class UpdateArticleStatusDto {
  @IsEnum(ArticleStatus, { message: '状态只有 draft / pending / published / locked' })
  @IsNotEmpty({ message: '状态不能为空' })
  status: ArticleStatus;
}

export class DeleteArticleDto {
  @IsNumber({}, { message: '元素必须是数字', each: true })
  @IsArray({ message: '必须是数组' })
  ids: number[];
}

export class QueryListDto {
  @Transform((params) =>
    typeof params.value == 'string' ? JSON.parse(params.value) : params.value,
  )
  @IsNotEmpty({ message: '参数不能为空' })
  lazyParams: LazyParams | LazyParamsWithPage;
}

export interface LazyParams {
  rows: number; // 每页数量
  sortField: string | null;
  sortOrder: 1 | -1 | null; // 1:升序 -1:降序
  filters: Record<string, DataTableOperatorFilterMetaData>;
}

export interface LazyParamsWithPage extends LazyParams {
  pageCount: number;
  page: number;
}

export interface DataTableOperatorFilterMetaData {
  value: string | null;
  matchMode:
    | 'startsWith'
    | 'contains'
    | 'notContains'
    | 'endsWith'
    | 'equals'
    | 'notEquals'
    | 'in'
    | 'lt'
    | 'lte'
    | 'gt'
    | 'gte'
    | 'between'
    | 'dateIs'
    | 'dateIsNot'
    | 'dateBefore'
    | 'dateAfter'
    | undefined;
}
